<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DeepSeek-V3 AI 聊天助手</title>
    <style>
        /* 样式保持不变 */
        :root {
            --primary-color: #4a6bdf;
            --secondary-color: #f0f2f5;
            --user-color: #4a6bdf;
            --bot-color: #10a37f;
        }

        body {
            font-family: 'Segoe UI', Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f9f9f9;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }

        .container {
            max-width: 900px;
            width: 100%;
            margin: 0 auto;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            padding: 20px;
            flex: 1;
            display: flex;
            flex-direction: column;
        }

        h1 {
            color: var(--primary-color);
            text-align: center;
            margin-bottom: 20px;
        }

        #chat-box {
            flex: 1;
            overflow-y: auto;
            padding: 15px;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            margin-bottom: 15px;
            background-color: var(--secondary-color);
        }

        .message {
            margin: 10px 0;
            padding: 10px 15px;
            border-radius: 18px;
            max-width: 80%;
            word-wrap: break-word;
        }

        .user {
            background-color: var(--user-color);
            color: white;
            margin-left: auto;
            border-bottom-right-radius: 4px;
        }

        .bot {
            background-color: white;
            color: #333;
            border: 1px solid #e0e0e0;
            margin-right: auto;
            border-bottom-left-radius: 4px;
        }

        .input-area {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }

        #user-input {
            width: 100%;
            min-height: 100px;
            padding: 12px 15px;
            border: 1px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            resize: vertical;
            font-family: 'Consolas', 'Courier New', monospace;
            box-sizing: border-box;
        }

        .button-area {
            display: flex;
            justify-content: flex-end;
        }

        button {
            background-color: var(--primary-color);
            color: white;
            border: none;
            padding: 10px 24px;
            border-radius: 24px;
            cursor: pointer;
            font-size: 16px;
        }

        button:hover {
            opacity: 0.9;
        }

        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }

        pre {
            background-color: #f5f5f5;
            padding: 12px;
            border-radius: 6px;
            overflow-x: auto;
            margin: 10px 0;
            border-left: 3px solid var(--primary-color);
        }

        code {
            font-family: 'Courier New', monospace;
            font-size: 14px;
            white-space: pre-wrap;
        }

        .code-block {
            position: relative;
        }

        .copy-btn {
            position: absolute;
            right: 5px;
            top: 5px;
            background: rgba(0, 0, 0, 0.1);
            border: none;
            border-radius: 4px;
            padding: 2px 5px;
            font-size: 12px;
            cursor: pointer;
        }

        .typing-indicator {
            display: inline-block;
            background-color: #e6e6e6;
            padding: 10px 15px;
            border-radius: 18px;
            margin: 5px 0;
        }

        .typing-dot {
            display: inline-block;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #999;
            margin: 0 2px;
            animation: typing-animation 1.4s infinite ease-in-out both;
        }

        .typing-dot:nth-child(1) {
            animation-delay: 0s;
        }

        .typing-dot:nth-child(2) {
            animation-delay: 0.2s;
        }

        .typing-dot:nth-child(3) {
            animation-delay: 0.4s;
        }

        @keyframes typing-animation {
            0%, 80%, 100% {
                transform: scale(0.8);
                opacity: 0.5;
            }
            40% {
                transform: scale(1);
                opacity: 1;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <h1>DeepSeek-V3 AI 聊天助手 (流式响应)</h1>
    <div id="chat-box"></div>
    <div class="input-area">
        <textarea id="user-input" placeholder="输入你的问题...（支持多行输入和代码粘贴）"></textarea>
        <div class="button-area">
            <button id="send-button" onclick="sendMessage()">发送</button>
        </div>
    </div>
</div>

<script>
    let currentBotMessage = null;
    let eventSource = null;

    document.getElementById('user-input').addEventListener('keydown', function (e) {
        // 检测Enter键
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault(); // 阻止默认换行行为
            sendMessage();
            }
    });

    // 确保DOM加载完成后再绑定事件
    document.addEventListener('DOMContentLoaded', function () {
        const input = document.getElementById('user-input');
        if (input) {
            input.addEventListener('keydown', handleKeyDown);
        }
    });

    function handleKeyDown(e) {
        // 检测Enter键且排除Shift+Enter
        const isSendShortcut = e.keyCode === 13 && !e.shiftKey;

        if (isSendShortcut) {
            e.preventDefault();
            sendMessage();
        }
    }


    function showTypingIndicator() {
        const chatBox = document.getElementById('chat-box');
        const typingIndicator = document.createElement('div');
        typingIndicator.id = 'typing-indicator';
        typingIndicator.classList.add('typing-indicator');
        typingIndicator.innerHTML = `
            <div class="typing-dot"></div>
            <div class="typing-dot"></div>
            <div class="typing-dot"></div>
        `;
        chatBox.appendChild(typingIndicator);
        chatBox.scrollTop = chatBox.scrollHeight;
    }

    function removeTypingIndicator() {
        const typingIndicator = document.getElementById('typing-indicator');
        if (typingIndicator) {
            typingIndicator.remove();
        }
    }

    function createBotMessage() {
        const chatBox = document.getElementById('chat-box');

        // 移除打字指示器
        removeTypingIndicator();

        // 创建新的AI消息容器
        currentBotMessage = document.createElement('div');
        currentBotMessage.classList.add('message', 'bot');
        currentBotMessage.innerHTML = '<strong>AI:</strong> ';

        chatBox.appendChild(currentBotMessage);
        chatBox.scrollTop = chatBox.scrollHeight;

        return currentBotMessage;
    }

    async function sendMessage() {
        const input = document.getElementById('user-input').value.trim();
        if (!input) return;

        // 禁用发送按钮，防止重复发送
        const sendButton = document.getElementById('send-button');
        sendButton.disabled = true;

        const chatBox = document.getElementById('chat-box');

        // 添加用户消息
        const userMessage = document.createElement('div');
        userMessage.classList.add('message', 'user');

        // 处理代码块显示
        if (input.includes('\n')) {
            const formattedInput = formatCodeBlocks(input);
            userMessage.innerHTML = `<strong>你:</strong>${formattedInput}`;
        } else {
            userMessage.textContent = input;
        }

        chatBox.appendChild(userMessage);

        document.getElementById('user-input').value = '';
        chatBox.scrollTop = chatBox.scrollHeight;

        // 显示打字指示器
        showTypingIndicator();

        try {
            // 使用Fetch API发送POST请求
            const response = await fetch('/chat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ input: input })
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            // 使用ReadableStream处理流式响应
            const reader = response.body.getReader();
            const decoder = new TextDecoder();

            // 创建AI消息容器
            createBotMessage();

            // 读取流数据
            while (true) {
                const { value, done } = await reader.read();
                if (done) break;

                // 解码数据
                const chunk = decoder.decode(value);
                const lines = chunk.split('\n');

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const data = JSON.parse(line.substring(6));

                        if (data.token) {
                            // 逐步添加token到AI消息
                            currentBotMessage.innerHTML += data.token;
                            chatBox.scrollTop = chatBox.scrollHeight;
                        }

                        if (data.done) {
                            // 处理代码块显示
                            const formattedResponse = formatCodeBlocks(currentBotMessage.innerHTML.replace('<strong>AI:</strong> ', ''));
                            currentBotMessage.innerHTML = `<strong>AI:</strong>${formattedResponse}`;

                            // 重新启用发送按钮
                            sendButton.disabled = false;
                            currentBotMessage = null;

                            // 添加复制按钮到代码块
                            addCopyButtons();

                            if (!data.continue) {
                                document.getElementById('user-input').disabled = true;
                                const endMessage = document.createElement('div');
                                endMessage.textContent = '聊天已结束。';
                                chatBox.appendChild(endMessage);
                            }

                            return;
                        }

                        if (data.error) {
                            throw new Error(data.error);
                        }
                    }
                }
            }
        } catch (error) {
            console.error('Error:', error);
            removeTypingIndicator();
            sendButton.disabled = false;

            const errorMessage = document.createElement('div');
            errorMessage.classList.add('message', 'bot');
            errorMessage.textContent = '发生错误，请稍后再试。';
            chatBox.appendChild(errorMessage);
            chatBox.scrollTop = chatBox.scrollHeight;
        }
    }

    function formatCodeBlocks(text) {
        // 处理代码块标记
        const codeBlockRegex = /```(\w*)\n([\s\S]*?)\n```/g;
        return text.replace(codeBlockRegex, (match, lang, code) => {
            const escapedCode = escapeHtml(code);
            return `<div class="code-block"><pre><code class="language-${lang}">${escapedCode}</code></pre><button class="copy-btn" onclick="copyToClipboard(this)">复制</button></div>`;
        }).replace(/\n/g, '<br>');
    }

    function addCopyButtons() {
        const codeBlocks = document.querySelectorAll('.code-block');
        codeBlocks.forEach(block => {
            if (!block.querySelector('.copy-btn')) {
                const copyBtn = document.createElement('button');
                copyBtn.classList.add('copy-btn');
                copyBtn.textContent = '复制';
                copyBtn.onclick = function() { copyToClipboard(this); };
                block.appendChild(copyBtn);
            }
        });
    }

    function escapeHtml(unsafe) {
        return unsafe
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    function copyToClipboard(button) {
        const codeBlock = button.previousElementSibling;
        const range = document.createRange();
        range.selectNode(codeBlock);
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(range);
        document.execCommand('copy');
        window.getSelection().removeAllRanges();

        button.textContent = '已复制';
        setTimeout(() => {
            button.textContent = '复制';
        }, 2000);
    }
</script>
</body>
</html>